package com.moji.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.moji.entity.UserInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @description: Jwt工具类，生成JWT和认证
 * @author: ccl
*/
@Component
public class JwtTokenUtil {

    private static final Logger logger = LoggerFactory.getLogger(JwtTokenUtil.class);

    private final static String TOKEN_HEADER = "Authorization";

    /**
     * 密钥
     */
    @Value("${jwt.secret}")
    private String secret;
    /**
     * 过期时间
     **/
    @Value("${jwt.expiration}")
    private Long expiration;

    /**
     * 生成用户token,设置token超时时间
     */
    public  String createToken(UserInfo user) {
        //过期时间
        Date expireDate = new Date(System.currentTimeMillis() + expiration * 1000);
        Map<String, Object> map = new HashMap<>();
        map.put("alg", "HS256");
        map.put("typ", "JWT");
        String token = JWT.create()
                .withHeader(map)// 添加头部
                //可以将基本信息放到claims中
                .withClaim("loginId", user.getLoginId())//登录账号
                .withClaim("userCode", user.getUserCode())//用户编码
                .withClaim("deptCode", user.getDeptCode())//部门编码
                .withClaim("userName", user.getUserName())//用户名称
                .withClaim("mobile", user.getMobile())//电话
                .withClaim("roleCode", user.getRoleCode())//角色
                .withExpiresAt(expireDate) //超时设置,设置过期的日期
                .withIssuedAt(new Date()) //签发时间
                .sign(Algorithm.HMAC256(secret)); //SECRET加密
        return token;
    }
    /**
     * 校验token并解析token
     */
    public  Map<String, Claim> verifyToken(String token) {
        JWTVerifier verifier = JWT.require(Algorithm.HMAC256(secret)).build();
        DecodedJWT jwt = verifier.verify(token);
        return jwt.getClaims();
    }

    /**
     * 获取HttpServletRequest
     * @return
     */
    public HttpServletRequest getRequestContextHolderRequest(){

        return ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
    }

    /**
     * 获取用户Token相关信息
     */
    public String getUserByToken(){
        return getRequestContextHolderRequest().getHeader(TOKEN_HEADER);
    }

    /**
     * 获取用户信息
     */
    public String getUserInfo(String key){
        Map<String, Claim> stringClaimMap = verifyToken(getUserByToken());
        return stringClaimMap.get(key).asString();
    }
}
